﻿using System;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace douban.sdk
{
    /// <summary>
    /// 获取access_token返回值
    /// </summary>
    public class AuthAccessToken
    {
        [JsonProperty("access_token")]
        public string Token { get; private set; }
        [JsonProperty("expires_in")]
        public int Expired { get; private set; }
        [JsonProperty("refresh_token")]
        public string RefreshToken { get; private set; }
        [JsonProperty("douban_user_id")]
        public string UserId { get; private set; }
    }

    public static partial class API
    {
        /// <summary>
        /// 获取authorization_code
        /// </summary>
        /// <param name="name">用户名</param>
        /// <param name="pwd">密码</param>
        /// <param name="scope">(可选)申请权限的范围</param>
        /// <returns>authorization_code</returns>
        public static async Task<string >AuthGetCode(string name, string pwd, string scope = null)
        {
            var ub = AuthGetCodeUrl();

            StringBuilder builder = new StringBuilder();
            builder.Append("user_email", name);
            builder.Append("user_passwd", pwd);
            builder.Append("confirm", "授权");
            using (HttpWebResponse res = await Utilities.GetResponse(ub, builder.ToString()))
            {
                int start = res.ResponseUri.Query.LastIndexOf("=");
                Common.AuthCode = res.ResponseUri.Query.Substring(start + 1);
                return Common.AuthCode;
            }
        }

        public static string AuthGetCodeUrl(string scope = null)
        {
            UriBuilder ub = new UriBuilder(Common.AUTHGETCODE);
            Utilities.AddParam(ref ub, "client_id", Common.APIKey);
            Utilities.AddParam(ref ub, "redirect_uri", Common.RedirectUri);
            Utilities.AddParam(ref ub, "response_type", Common.RESPONSETYPE);
            Utilities.AddParam(ref ub, "scope", scope);
            return ub.ToString();
        }

        /// <summary>
        /// 获得Token
        /// </summary>
        /// <returns>AccessToken</returns>
        public static async Task<AuthAccessToken> AuthGetToken()
        {
            string result = await Utilities.RequestPost(Common.AUTHTOKENOP, AuthGetTokenData());
            if (string.IsNullOrEmpty(result))
                return null;
            AuthAccessToken token = (AuthAccessToken)Utilities.JsonDeserialize<AuthAccessToken>(result);
            Common.Token = token.Token;
            Common.RefreshToken = token.RefreshToken;
            Common.UserId = token.UserId;
            return token;
        }

        public static string AuthGetTokenData()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("client_id", Common.APIKey);
            builder.Append("client_secret", Common.Secret);
            builder.Append("redirect_uri", Common.RedirectUri);
            builder.Append("grant_type", Common.GRANTTYPE_GETCODE);
            builder.Append("code", Common.AuthCode);
            //builder.Append("confirm", "授权");
            return builder.ToString();
        }

        /// <summary>
        /// 更换Token
        /// </summary>
        /// <returns>AccessToken</returns>
        public static async Task< AuthAccessToken >AuthRefreshToken()
        {
            string result = await Utilities.RequestPost(Common.AUTHTOKENOP, AuthRefreshTokenData());
            AuthAccessToken token = (AuthAccessToken)Utilities.JsonDeserialize<AuthAccessToken>(result);
            Common.Token = token.Token;
            Common.RefreshToken = token.RefreshToken;
            return token;
        }

        public static string AuthRefreshTokenData()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append( "client_id", Common.APIKey);
            builder.Append( "client_secret", Common.Secret);
            builder.Append( "redirect_uri", Common.RedirectUri);
            builder.Append( "grant_type", Common.GRANTTYPE_REFRESH);
            builder.Append( "refresh_token", Common.RefreshToken);

            return builder.ToString();
        }
    }
}
